<!--
 * @Author: Charsen
 * @Date: 2025-07-24 08:33
 * @LastEditors: wjc
 * @LastEditTime: 2025-10-29 17:56:39
 * @Description: 
-->
<template>
  <Content>
    <!-- 使用 SearchHeader 公共组件 -->
    <SearchHeader
      ref="searchHeaderRef"
      :search-former="searchFormer"
      container-class="flex-y-center justify-between mb-10px"
      @on-search="handleSearch"
      @on-reset="handleSearch"
    >
      <template #right-buttons>
        <slot name="right-top-button">
          <template v-if="showCreate && checkAction(actions.add)">
            <OptionAdd v-if="createSinglePage" :right="true" @on-add="goCreatePage" />
            <OptionAdd v-else :right="true" @on-add="showCreator" />
          </template>
        </slot>
        <slot name="right-top-button-append"></slot>
      </template>
    </SearchHeader>

    <slot name="statistic" v-bind="statistic"></slot>

    <!-- 使用 TableWrapper 公共组件 -->
    <TableWrapper
      ref="tableWrapperRef"
      :left-span="leftSpan"
      :columns="columns"
      :list="list"
      :actions="actions"
      :loading="listLoading"
      :multi-select="multiSelect"
      :table-index="tableIndex"
      :page-former="pageFormer"
      row-class="body-container"
      @selection-change="handleSelectionChange"
      @on-show="showShower"
      @on-edit="showEditor"
      @on-edit-page="goEditPage"
      @on-del="handleDelete"
      @on-force-del="handleDelete"
      @on-restore="handleDelete"
    >
      <template #left>
        <slot name="left"></slot>
      </template>

      <template #header-options>
        <div>
          <el-button
            v-if="multiSelect"
            v-action="actions.delBatch"
            :disabled="multipleSelection.length === 0"
            size="small"
            type="danger"
            @click="handleDeleteBatch"
          >
            删除
            <span class="i-custom-delete ml-6px wh-12px"></span>
          </el-button>

          <slot name="header-options"></slot>
        </div>

        <OptionTrashed
          v-if="showTrashed"
          v-action="actions.trashed"
          :return-by-query="returnByQuery"
          :trashed-route="getTrashedRoute(trashedRoute)"
          :show-text="true"
        />
      </template>

      <!-- 传递所有列插槽 -->
      <template v-for="(_, name) in $slots" #[name]="slotData">
        <slot :name="name" v-bind="slotData"></slot>
      </template>

      <template #pagination>
        <Pagination
          v-model:limit="pageFormer.page_limit"
          v-model:page="pageFormer.page"
          :total="pageFormer.total"
          @on-changed="loadData"
        />
      </template>
    </TableWrapper>

    <Creator
      v-model:visible="createDialog.visible"
      :form-size="createDialog.size"
      :entity="createDialog.entity"
      :request-url="requestUrl"
      @on-stored="loadData"
    />

    <Editor
      v-model:visible="editDialog.visible"
      :entity-id="editDialog.id"
      :form-size="editDialog.size"
      :entity="editDialog.entity"
      :request-url="requestUrl"
      @on-updated="handleUpdateWithEmit"
    />

    <Shower
      v-model:visible="showDialog.visible"
      :entity-id="showDialog.id"
      :entity="showDialog.entity"
      :form-size="showDialog.size"
      :request-url="requestUrl"
    >
      <template v-for="(_, name) in $slots" #[name]="slotData">
        <slot :name="name" v-bind="slotData"></slot>
      </template>
    </Shower>
  </Content>
</template>

<script setup lang="ts">
  import { useCreator } from '#/hooks/useCreator'
  import { useDestroy } from '#/hooks/useDestroy'
  import { useEditor } from '#/hooks/useEditor'
  import { useLister } from '#/hooks/useLister'
  import { useShower } from '#/hooks/useShower'
  import checkAction from '#/utils/check-action'

  import SearchHeader from './components/SearchHeader.vue'
  import TableWrapper from './components/TableWrapper.vue'

  defineOptions({
    name: 'Scaffold',
  })

  const props = withDefaults(
    defineProps<{
      actions: AclPermission
      createSinglePage?: boolean
      entity: string
      formSize?: string
      leftSpan?: number
      multiSelect?: boolean
      requestUrl?: RequestUrl
      returnByQuery?: boolean
      showCreate?: boolean
      showTrashed?: boolean
      tableIndex?: boolean
      trashedRoute?: string
    }>(),
    {
      trashedRoute: '',
      actions: () =>
        ({
          add: '',
          edit: '',
          del: '',
          delBatch: '',
          trashed: '',
        }) as AclPermission,
      requestUrl: () => ({}) as RequestUrl,
      multiSelect: true,
      showCreate: true,
      showTrashed: true,
      tableIndex: true,
      createSinglePage: false,
      returnByQuery: false,
      leftSpan: 0,
      formSize: 'mini',
    }
  )

  const emits = defineEmits<{
    (e: 'on-fetched', res: object): void
    (e: 'on-deleted', res: any): void
    (e: 'on-updated', res: object): void
  }>()
  const searchHeaderRef = ref()
  const tableWrapperRef = ref()
  const multipleSelection = ref([])

  const {
    searchFormer,
    pageFormer,
    list,
    listLoading,
    columns,
    statistic,
    handleSearchChange,
    handleSearchChangeWith,
    fetchData,
    fetchDataWith,
    goEditPage,
    goCreatePage,
    getTrashedRoute,
    updateListWithOne,
  } = useLister({
    entity: props.entity,
    url: props.requestUrl,
  })

  const { handleDestroy, handleDestroyWith, handleDestroyBatch, handleDestroyBatchWith } =
    useDestroy({
      entity: props.entity,
      list,
    })
  const hookOptions = { entity: props.entity, formSize: props.formSize }
  const { showDialog, showShower } = useShower(hookOptions)
  const { createDialog, showCreator } = useCreator(hookOptions)
  const { editDialog, showEditor } = useEditor(hookOptions)

  const handleSelectionChange = (val: any) => (multipleSelection.value = val)
  const getSearchFormData = () => searchHeaderRef.value?.getSearchFormData()

  const handleDelete = (id: number | string) => {
    const onDestroyed = (res: any) => emits('on-deleted', res)
    props.requestUrl.destroy
      ? handleDestroyWith({ destroy: props.requestUrl.destroy, params: { ids: [id] } }, onDestroyed)
      : handleDestroy(id, onDestroyed)
  }

  const handleDeleteBatch = () => {
    const selectIds = multipleSelection.value.map((item: any) => item.id)

    const onDestroyed = (res: any) => {
      multipleSelection.value = []
      // 通过TableWrapper组件清除选择
      emits('on-deleted', res)
    }

    props.requestUrl.destroyBatch
      ? handleDestroyBatchWith(
          { destroyBatch: props.requestUrl.destroyBatch, params: { ids: selectIds } },
          onDestroyed
        )
      : handleDestroyBatch(selectIds, onDestroyed)
  }

  const handleUpdateWithEmit = (model: object) => {
    updateListWithOne(model, editDialog.value.index)
    emits('on-updated', model)
  }

  const handleSearch = (data: object) => {
    props.requestUrl.index
      ? handleSearchChangeWith(data, { index: props.requestUrl.index })
      : handleSearchChange(data)
  }

  const loadData = () => {
    const onFetched = (res: object) => {
      emits('on-fetched', res)
    }
    props.requestUrl.index
      ? fetchDataWith({ index: props.requestUrl.index, params: props.requestUrl.params }, onFetched)
      : fetchData(onFetched)
  }

  defineExpose({
    searchFormer,
    getSearchFormData,
    loadData,
  })

  onMounted(() => {
    loadData()
  })
</script>
<style lang="scss" scoped></style>
